package com.coincalf.framework.utils;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class SignUtil {

    private static final String SIGN_KEY = "eaad5382-6df7-4558-b25a-0fed4ea82214";

    /**
     * 参数排序并转字符串
     */
    private static String getStrByParameterJson(Map<String, String> map, String... exclude) {
        if (map != null) {
            // 排除
            for (String key : exclude) {
                map.remove(key);
            }
            // 遍历
            StringBuilder sb = new StringBuilder();
            Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
            boolean hasNext = iterator.hasNext();
            while (hasNext) {
                Map.Entry<String, String> entry = iterator.next();
                Object value = entry.getValue();
                if (value != null && !StringUtils.isEmpty(value.toString())) {
                    sb.append(entry.getKey()).append('=').append(value);
                }
                if (hasNext = iterator.hasNext()) {
                    sb.append('&');
                }
            }
            return sb.toString();
        }
        return null;
    }

    private static String sign(byte[] dataBytes, String key) {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), "HmacMD5");
        Mac mac;
        try {
            mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
        } catch (Exception e) {
            log.warn("数据加密异常 e={}", e.getMessage());
            return null;
        }
        byte[] bytes = mac.doFinal(dataBytes);
        return Hex.toHexString(bytes);
    }

    /**
     * 生成签名
     *
     * @param currentTime
     * @param randomNum
     * @return
     */
    public static String createSign(String currentTime, String randomNum) {
        Map<String, String> map = new HashMap<>(4);
        map.put("currentTime", currentTime);
        map.put("randomNum", randomNum);
        String inputStr = getStrByParameterJson(map);
        byte[] inputData = inputStr.getBytes();
        return SignUtil.sign(inputData, SignUtil.SIGN_KEY);
    }

    public static boolean verifySign(String currentTime, String randomNum, String sign) {
        if (StringUtils.isEmpty(currentTime) || StringUtils.isEmpty(randomNum)) {
            return false;
        }
        Map<String, String> map = new HashMap<>(4);
        map.put("currentTime", currentTime);
        map.put("randomNum", randomNum);
        String inputStr = getStrByParameterJson(map);
        byte[] inputData = inputStr.getBytes();
        return SignUtil.sign(inputData, SignUtil.SIGN_KEY).equals(sign);
    }

    public static void main(String[] args) {
        System.out.println(createSign("123", "123"));
    }

}
